package com.unlcn.ils.wms.backend.service.outbound.impl;

import cn.huiyunche.commons.domain.PageVo;
import cn.huiyunche.commons.exception.BusinessException;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.unlcn.ils.wms.backend.bo.outboundBO.WmsShipmentPlanRejectBO;
import com.unlcn.ils.wms.backend.enums.*;
import com.unlcn.ils.wms.backend.service.inbound.WmsInventoryService;
import com.unlcn.ils.wms.backend.service.outbound.WmsShipmentPlanRejectService;
import com.unlcn.ils.wms.backend.service.webservice.client.WmsJmDcsService;
import com.unlcn.ils.wms.backend.util.DateUtils;
import com.unlcn.ils.wms.base.dto.*;
import com.unlcn.ils.wms.base.mapper.additional.WmsInventoryLocationExtMapper;
import com.unlcn.ils.wms.base.mapper.extmapper.WmsShipmentPlanCancelExtMapper;
import com.unlcn.ils.wms.base.mapper.extmapper.WmsShipmentPlanRejectExtMapper;
import com.unlcn.ils.wms.base.mapper.inbound.WmsInboundAllocationMapper;
import com.unlcn.ils.wms.base.mapper.inbound.WmsWarehouseNoticeDetailMapper;
import com.unlcn.ils.wms.base.mapper.junmadcs.WmsHandoverOrderMapper;
import com.unlcn.ils.wms.base.mapper.junmadcs.WmsShipmentPlanCancelMapper;
import com.unlcn.ils.wms.base.mapper.outbound.WmsOutboundTaskMapper;
import com.unlcn.ils.wms.base.mapper.outbound.WmsPreparationPlanMapper;
import com.unlcn.ils.wms.base.mapper.outbound.WmsPreparationVehicleDetailMapper;
import com.unlcn.ils.wms.base.mapper.stock.WmsInventoryLocationMapper;
import com.unlcn.ils.wms.base.mapper.stock.WmsShipmentPlanMapper;
import com.unlcn.ils.wms.base.mapper.sys.SysUserMapper;
import com.unlcn.ils.wms.base.model.inbound.WmsInboundAllocation;
import com.unlcn.ils.wms.base.model.inbound.WmsInboundAllocationExample;
import com.unlcn.ils.wms.base.model.inbound.WmsWarehouseNoticeDetail;
import com.unlcn.ils.wms.base.model.inbound.WmsWarehouseNoticeDetailExample;
import com.unlcn.ils.wms.base.model.junmadcs.WmsHandoverOrder;
import com.unlcn.ils.wms.base.model.junmadcs.WmsHandoverOrderExample;
import com.unlcn.ils.wms.base.model.junmadcs.WmsShipmentPlanCancel;
import com.unlcn.ils.wms.base.model.junmadcs.WmsShipmentPlanCancelExample;
import com.unlcn.ils.wms.base.model.outbound.*;
import com.unlcn.ils.wms.base.model.stock.*;
import com.unlcn.ils.wms.base.model.sys.SysUser;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 发运计划驳回
 */
@Service
public class WmsShipmentPlanRejectServiceImpl implements WmsShipmentPlanRejectService {

    private Logger logger = LoggerFactory.getLogger(WmsShipmentPlanRejectServiceImpl.class);

    @Autowired
    private WmsShipmentPlanMapper shipmentPlanMapper;

    @Autowired
    private WmsShipmentPlanRejectExtMapper shipmentPlanRejectExtMapper;

    @Autowired
    private WmsPreparationVehicleDetailMapper preparationVehicleDetailMapper;

    @Autowired
    private WmsPreparationPlanMapper preparationPlanMapper;

    @Autowired
    private WmsOutboundTaskMapper wmsOutboundTaskMapper;

    @Autowired
    private WmsInventoryService wmsInventoryService;

    @Autowired
    private WmsShipmentPlanCancelMapper shipmentPlanCancelMapper;

    @Autowired
    private WmsWarehouseNoticeDetailMapper wmsWarehouseNoticeDetailMapper;

    @Autowired
    private WmsInventoryLocationMapper inventoryLocationMapper;

    private WmsInventoryLocationMapper wmsInventoryLocationMapper;

    private WmsJmDcsService wmsJmDcsService;

    private WmsShipmentPlanCancelExtMapper cancelExtMapper;

    private SysUserMapper sysUserMapper;

    private WmsInboundAllocationMapper wmsInboundAllocationMapper;

    private WmsHandoverOrderMapper wmsHandoverOrderMapper;

    private WmsInventoryLocationExtMapper wmsInventoryLocationExtMapper;

    @Autowired
    public void setWmsInventoryLocationExtMapper(WmsInventoryLocationExtMapper wmsInventoryLocationExtMapper) {
        this.wmsInventoryLocationExtMapper = wmsInventoryLocationExtMapper;
    }

    @Autowired
    public void setWmsHandoverOrderMapper(WmsHandoverOrderMapper wmsHandoverOrderMapper) {
        this.wmsHandoverOrderMapper = wmsHandoverOrderMapper;
    }

    @Autowired
    public void setWmsInboundAllocationMapper(WmsInboundAllocationMapper wmsInboundAllocationMapper) {
        this.wmsInboundAllocationMapper = wmsInboundAllocationMapper;
    }

    @Autowired
    public void setSysUserMapper(SysUserMapper sysUserMapper) {
        this.sysUserMapper = sysUserMapper;
    }

    @Autowired
    public void setCancelExtMapper(WmsShipmentPlanCancelExtMapper cancelExtMapper) {
        this.cancelExtMapper = cancelExtMapper;
    }

    @Autowired
    public void setWmsInventoryLocationMapper(WmsInventoryLocationMapper wmsInventoryLocationMapper) {
        this.wmsInventoryLocationMapper = wmsInventoryLocationMapper;
    }

    @Autowired
    public void setWmsJmDcsService(WmsJmDcsService wmsJmDcsService) {
        this.wmsJmDcsService = wmsJmDcsService;
    }


    /**
     * 列表分页查询
     */
    @Override
    public Map<String, Object> queryRejectList(WmsShipmentPlanRejectBO shipmentPlanRejectBO) {
        logger.info("WmsShipmentPlanRejectServiceImpl.queryRejectList param: {}", shipmentPlanRejectBO);
        checkParam(shipmentPlanRejectBO);
        //设置查询条件
        Map<String, Object> paramMap = new HashMap<>();

        setQueryExample(paramMap, shipmentPlanRejectBO);
        paramMap.put("spSendBusinessFlag", StringUtils.isBlank(shipmentPlanRejectBO.getSpSendBusinessFlag()) ?
                SendBusinessFlagEnum.SEND_Y.getValue() : shipmentPlanRejectBO.getSpSendBusinessFlag());
        paramMap.put("whCode", shipmentPlanRejectBO.getWhCode());
        paramMap.put("limitStart", shipmentPlanRejectBO.getStartIndex());
        paramMap.put("limitEnd", shipmentPlanRejectBO.getPageSize());
        paramMap.put("spDeliverWarehouseCode", shipmentPlanRejectBO.getSpDeliverWarehouseCode());
        paramMap.put("orderByClause", " gmt_create desc, sp_id desc ");

        PageVo pageVo = new PageVo();
        pageVo.setPageNo(shipmentPlanRejectBO.getPageNo());
        pageVo.setPageSize(shipmentPlanRejectBO.getPageSize());
        pageVo.setTotalRecord(shipmentPlanRejectExtMapper.countRejectPlanList(paramMap));

        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("page", pageVo);
        List<WmsShipmentPlanRejectDTO> rejectDTOList = shipmentPlanRejectExtMapper.queryRejectPlanList(paramMap);
        if (CollectionUtils.isNotEmpty(rejectDTOList)) {
            rejectDTOList.stream()
                    .filter(reject -> reject != null && reject.getSpId() != null)
                    .filter(reject -> reject.getSpRejectNum() != null && reject.getSpRejectNum() > 0L)
                    .forEach(reject -> reject.setSpIsReject(ShipmentPlanRejectStatusEnum.REJECT_ED.getCode()));
        }
        resultMap.put("dataList", rejectDTOList);
        return resultMap;
    }


    /**
     * 驳回--已经备料但无车可换的数据
     * <p>
     * 2018-2-6 调整驳回之后 修改交接单数据  删除接口表数据
     * 2018-2-7  bugfix更新库存驳回的车为正常在库
     * </p>
     *
     * @param spId 驳回的发运计划id
     */
    @Override
    public void updateToReject(Long spId) {
        logger.info("WmsShipmentPlanRejectServiceImpl.updateToReject spId: {}", spId);
        if (spId == null) {
            throw new BusinessException("请选择要驳回的发运计划");
        }
        WmsShipmentPlan shipmentPlan = checkReject(spId);

        //更新状态是否已驳回
        shipmentPlan.setSpIsReject(ShipmentPlanRejectStatusEnum.REJECT_ED.getCode());

        //更新状态
        shipmentPlanMapper.updateByPrimaryKeySelective(shipmentPlan);

        WmsShipmentPlanCancel cancelShip = getCancelList(shipmentPlan);
        shipmentPlanCancelMapper.insertSelective(cancelShip);
        //交接单接口表数据去掉已驳回车辆
        WmsHandoverOrderExample orderExample = new WmsHandoverOrderExample();
        orderExample.createCriteria().andGbnoEqualTo(shipmentPlan.getSpGroupBoardNo())
                .andVbelnEqualTo(shipmentPlan.getSpOrderNo())
                .andMatnrEqualTo(shipmentPlan.getSpMaterialCode());
        List<WmsHandoverOrder> wmsHandoverOrders = wmsHandoverOrderMapper.selectByExample(orderExample);
        if (CollectionUtils.isNotEmpty(wmsHandoverOrders)) {
            WmsHandoverOrder wmsHandoverOrder = wmsHandoverOrders.get(0);
            if (String.valueOf(WmsPreparationPlanEnum.WMS_PLAN_FINISH.getValue()).equals(wmsHandoverOrder.getPreparationStatus())) {
                throw new BusinessException("该组板单号:" + wmsHandoverOrder.getGbno() + "已经发运出库,不再支持驳回!");
            }
            String vin = wmsHandoverOrder.getSernr();
            // 2018-2-7  bugfix更新库存驳回的车为正常在库
            WmsInventoryLocation location = new WmsInventoryLocation();
            location.setStatus(InventoryLocationStatusEnum.NORMAL_10.getCode());
            location.setGmtUpdate(new Date());
            WmsInventoryLocationExample example = new WmsInventoryLocationExample();
            example.createCriteria().andInvlocVinEqualTo(vin);
            wmsInventoryLocationMapper.updateByExampleSelective(location, example);
            wmsHandoverOrderMapper.deleteByPrimaryKey(wmsHandoverOrder.getDataId());
        }
        //另起线程调用-驳回接口
        new Thread(() -> {
            try {
                wmsJmDcsService.updateBillCancelAction(cancelShip);
            } catch (BusinessException e) {
                logger.error("调用DCS发运驳回接口失败 BusinessException:", e);
                e.printStackTrace();
            } catch (Exception ex) {
                logger.error("调用DCS发运驳回接口失败 error:", ex);
                ex.printStackTrace();
            }
        }).start();

    }

    /**
     * 驳回未处理列表的列表返回
     * <p>
     * 2018-3-7 新需求:未处理的发运计划支持驳回
     * </p>
     *
     * @param spId 参数封装
     */
    @Override
    public List<WmsShipmentPlan> getNotHandleRejectList(Long spId, String whCode) {
        logger.info("WmsShipmentPlanRejectServiceImpl.getNotHandleRejectList spId: {}", spId);
        if (StringUtils.isBlank(whCode))
            throw new BusinessException("仓库code不能为空!");
        if (!(WhCodeEnum.JM_CS.getValue().equals(whCode) || WhCodeEnum.JM_XY.getValue().equals(whCode)))
            throw new BusinessException("此仓库不支持该操作!");
        if (spId == null) {
            throw new BusinessException("请选择要驳回的发运计划");
        }
        HashMap<String, Object> params = Maps.newHashMap();
        params.put("spId", spId);
        params.put("whCode", whCode);
        List<WmsShipmentPlan> list = shipmentPlanRejectExtMapper.selectGroupListBySpId(params);
        if (CollectionUtils.isEmpty(list)) {
            throw new BusinessException("未查询到对应的列表数据");
        }
        if (String.valueOf(SendBusinessFlagEnum.SEND_Y.getValue()).equals(list.get(0).getSpSendBusinessFlag())) {
            throw new BusinessException("对应的发运计划列表已经备料,不支持直接驳回");
        }
        return list;
    }


    /**
     * 驳回-未进行备料的数据
     * <p>
     * 2018-3-7 新需求:新增针对驳回未处理发运计划数据
     * </p>
     *
     * @param dto 参数封装
     */
    @Override
    public void updateToRejectNotHandle(WmsRejectUndealDTO dto) {
        logger.info("WmsShipmentPlanRejectServiceImpl.updateToRejectNotHandle params:{}", JSONObject.toJSONString(dto));
        if (dto == null)
            throw new BusinessException("传入参数为空!");
        String whCode = dto.getWhCode();
        String spIds = dto.getSpIds();
        if (StringUtils.isBlank(spIds))
            throw new BusinessException("请选择需要驳回的计划");
        if (StringUtils.isBlank(whCode))
            throw new BusinessException("仓库code不能为空!");
        if (!(WhCodeEnum.JM_XY.getValue().equals(whCode) || WhCodeEnum.JM_CS.getValue().equals(whCode)))
            throw new BusinessException("该仓库不支持此操作!");
        SysUser sysUser = sysUserMapper.selectByPrimaryKey(Integer.valueOf(dto.getUserId()));
        String[] split_ids = spIds.split(",");
        List<String> ids = Arrays.asList(split_ids);
        List<WmsShipmentPlan> rejectList = shipmentPlanRejectExtMapper.selectRejectListByIds(ids);
        ArrayList<WmsShipmentPlanCancel> cancelList = Lists.newArrayList();
        rejectList.forEach((WmsShipmentPlan v) -> {
            if (String.valueOf(SendBusinessFlagEnum.SEND_Y.getValue()).equals(v.getSpSendBusinessFlag())) {
                throw new BusinessException("该发运计划订单:" + v.getSpOrderNo() + "已经创建备料计划,只能通过无车可换驳回!");
            }
            if (ShipmentPlanRejectStatusEnum.REJECT_ED.getCode().equals(v.getSpIsReject())) {
                throw new BusinessException("该发运计划订单:" + v.getSpOrderNo() + "已经驳回,不能再进行此操作!");
            }
            WmsShipmentPlanCancel cancel = getCancelList(v);
            cancel.setCreateUserName(sysUser == null ? null : sysUser.getName());
            cancel.setModifyUserName(sysUser == null ? null : sysUser.getName());
            cancel.setPbBackQuantity(v.getSpGroupBoardQuantity());
            cancelList.add(cancel);
        });
        cancelExtMapper.insertCancelBatch(cancelList);
        HashMap<String, Object> params = Maps.newHashMap();
        params.put("rj_status", ShipmentPlanRejectStatusEnum.REJECT_ED.getCode());
        params.put("sp_list", rejectList);
        shipmentPlanRejectExtMapper.updateShipmentRejectStatusBatch(params);
    }

    /**
     * 发运驳回的前置校验
     *
     * @param spId 发运计划id
     * @return 返回值
     */
    private WmsShipmentPlan checkReject(Long spId) {

        WmsShipmentPlan shipmentPlan = shipmentPlanMapper.selectByPrimaryKey(spId);
        if (shipmentPlan == null) {
            throw new BusinessException("找不到对应的发运计划");
        }
        if (shipmentPlan.getSpRejectNum() == null || shipmentPlan.getSpRejectNum() <= 0) {
            throw new BusinessException("驳回数量要不小于0");
        }
        if (ShipmentPlanRejectStatusEnum.REJECT_ED.getCode().equals(shipmentPlan.getSpIsReject())) {
            throw new BusinessException("当前计划已驳回");
        }

        //校验是否有驳回
        WmsShipmentPlanCancelExample cancelExample = new WmsShipmentPlanCancelExample();
        cancelExample.createCriteria().andPbGroupBoardNoEqualTo(shipmentPlan.getSpGroupBoardNo());
        int cancleCount = shipmentPlanCancelMapper.countByExample(cancelExample);
        if (cancleCount > 0) {
            throw new BusinessException("当前计划已驳回");
        }
        //校验任务中是否有未处理的数据
        List<WmsOutboundTask> taskList = getTaskByHandoverNoList(getPlanListByGroupNo(shipmentPlan.getSpGroupBoardNo()));
        if (CollectionUtils.isNotEmpty(taskList)) {
            taskList.forEach(task -> {
                if (task != null) {
                    if ((String.valueOf(WmsOutboundTaskStatusEnum.WMS_OUTBOUND_TASK_CANCLE.getValue()).equals(task.getOtStatus())
                            && TaskIsNeedChangeEnum.NO_CHANGE.getCode().equals(task.getOtIsChange()))
                            || (String.valueOf(WmsOutboundTaskStatusEnum.WMS_OUTBOUND_TASK_STATUS_FINISHED.getValue()).equals(task.getOtStatus())
                            && TmsInspectStatusEnum.WAYBILL_EXCP.getValue() == task.getInspectStatus()
                            && TaskIsNeedChangeEnum.NO_CHANGE.getCode().equals(task.getOtIsChange()))) {
                        throw new BusinessException("存在未处理的数据");
                    }
                }
            });
        }
        return shipmentPlan;
    }

    /**
     * 获取详情列表
     */
    @Override
    public List<WmsShipmentPlanRejectDetailDTO> queryDetailList(Long spId) {
        logger.info("WmsShipmentPlanRejectServiceImpl.queryDetailList spId: {}", spId);
        WmsShipmentPlan shipmentPlan = checkShipment(spId);
        List<WmsShipmentPlan> shipmentList = getShipmentList(shipmentPlan.getSpGroupBoardNo());
        //String handoverNo = shipmentPlan.getHoHandoverNumber();

        List<WmsShipmentPlanRejectDetailDTO> detailDTOList = null;

        //if (CollectionUtils.isNotEmpty(shipmentList)) {
        //    detailDTOList = new ArrayList<>();
        //    WmsShipmentPlanRejectDetailDTO detailDTO = null;
        //    for (WmsShipmentPlan foreachShipment : shipmentList) {
        //        if (foreachShipment != null) {
        //            detailDTO = new WmsShipmentPlanRejectDetailDTO();
        //            detailDTO.setVin(foreachShipment.getSpVin());//车架号
        //            detailDTO.setVehicleName(foreachShipment.getSpVehicleName());//车型
        //            detailDTO.setHandoverNo(foreachShipment.getHoHandoverNumber());//交接单号
        //
        //            //备料详情信息
        //            WmsPreparationVehicleDetail detailByVin = getDetailByVin(foreachShipment.getSpVin());
        //            //setDetailInfo(detailDTO, detailByVin);
        //            //设置检验结果
        //            setCheckInfo(detailDTO, getTaskByVin(foreachShipment.getSpVin()));
        //            //主表信息
        //            if (detailByVin != null) {
        //                detailDTO.setPlanDetailId(detailByVin.getVdId());
        //                setPlanInfo(detailDTO, getPreparationPlan(detailByVin.getVdPpId()));
        //            }
        //            //设置是否需要换车
        //            detailDTOList.add(detailDTO);
        //        }
        //    }
        //}

        List<WmsOutboundTask> taskList = getTaskByHandoverNoList(getPlanListByGroupNo(shipmentPlan.getSpGroupBoardNo()));
        if (CollectionUtils.isNotEmpty(taskList)) {
            detailDTOList = new ArrayList<>();
            WmsShipmentPlanRejectDetailDTO detailDTO;
            for (WmsOutboundTask task : taskList) {
                if (task != null) {
                    detailDTO = new WmsShipmentPlanRejectDetailDTO();
                    detailDTO.setVin(task.getOtVin());//车架号
                    //发运计划
                    //setShipmentInfo(detailDTO, getShipmentByVin(task.getOtVin()));
                    //备料详情信息
                    WmsPreparationVehicleDetail detailByVin = getDetailByVin(task.getOtVin(), task.getOtBlId());
                    //设置检验结果
                    setCheckInfo(detailDTO, task);
                    //主表信息
                    if (detailByVin != null && !TaskIsNeedChangeEnum.CHANGE_ED.getCode().equals(task.getOtIsChange())) {
                        detailDTO.setPlanDetailId(detailByVin.getVdId());
                        detailDTO.setHandoverNo(task.getHoHandoverNumber());//交接单号
                        setPlanInfo(detailDTO, getPreparationPlan(detailByVin.getVdPpId()));
                    }
                    detailDTO.setVehicleName(task.getOtVehicleSpecName());//车型
                    //设置是否需要换车
                    detailDTOList.add(detailDTO);
                }
            }
        }
        return detailDTOList;
    }

    ///**
    // * 根据车架号获取发运计划
    // *
    // * @param vin
    // * @return
    // */
    //private WmsShipmentPlan getShipmentByVin(String vin) {
    //    if (StringUtils.isNotBlank(vin)) {
    //        WmsShipmentPlanExample example = new WmsShipmentPlanExample();
    //        example.createCriteria().andSpVinEqualTo(vin);
    //
    //        List<WmsShipmentPlan> wmsShipmentPlanList = shipmentPlanMapper.selectByExample(example);
    //        if (CollectionUtils.isNotEmpty(wmsShipmentPlanList)) {
    //            return wmsShipmentPlanList.get(0);
    //        }
    //    }
    //    return null;
    //}

    /**
     * 设置信息
     */
    private void setShipmentInfo(WmsShipmentPlanRejectDetailDTO detailDTO, WmsShipmentPlan shipmentPlan) {
        if (shipmentPlan != null) {
            detailDTO.setVehicleName(shipmentPlan.getSpVehicleName());//车型
            detailDTO.setHandoverNo(shipmentPlan.getHoHandoverNumber());//交接单号
        }
    }

    /**
     * 根据组版单号获取数据
     */
    private List<String> getPlanListByGroupNo(String groupNo) {
        //交接单集合
        List<String> handoverNoList = new ArrayList<>();
        if (StringUtils.isNotBlank(groupNo)) {
            WmsShipmentPlanExample example = new WmsShipmentPlanExample();
            example.createCriteria().andSpGroupBoardNoEqualTo(groupNo);

            List<WmsShipmentPlan> wmsShipmentPlanList = shipmentPlanMapper.selectByExample(example);
            if (CollectionUtils.isNotEmpty(wmsShipmentPlanList)) {
                wmsShipmentPlanList.stream()
                        .filter(shipPlan -> shipPlan != null && StringUtils.isNotBlank(shipPlan.getHoHandoverNumber()))
                        .forEach(shipment -> handoverNoList.add(shipment.getHoHandoverNumber()));
            }
        }
        return handoverNoList;
    }

    /**
     * 根据交接单获取出库作业数据
     */
    private List<WmsOutboundTask> getTaskByHandoverNoList(List<String> handoverNoList) {
        if (CollectionUtils.isNotEmpty(handoverNoList)) {
            WmsOutboundTaskExample taskExample = new WmsOutboundTaskExample();
            taskExample.createCriteria().andHoHandoverNumberIn(handoverNoList);

            return wmsOutboundTaskMapper.selectByExample(taskExample);
        }
        return null;
    }


    /**
     * 任务取消 --君马库
     * <p>
     * 2018-1-26 修复任务取消时更新旧的车为正常在库状态
     * </p>
     *
     * @param wmsShipmentPlanRejectBO 参数封装
     */
    @Override
    public void updateToCancleTask(WmsShipmentPlanRejectBO wmsShipmentPlanRejectBO) {
        logger.info("WmsShipmentPlanRejectServiceImpl.updateToCancleTask spId: {}", wmsShipmentPlanRejectBO);
        checkParam(wmsShipmentPlanRejectBO);
        if (StringUtils.isBlank(wmsShipmentPlanRejectBO.getCancleReason())
                || wmsShipmentPlanRejectBO.getTaskId() == null) {
            throw new BusinessException("取消原因为空");
        }
        if (StringUtils.isBlank(wmsShipmentPlanRejectBO.getWhCode()))
            throw new BusinessException("仓库code为空!");

        WmsOutboundTask outboundTask = wmsOutboundTaskMapper.selectByPrimaryKey(wmsShipmentPlanRejectBO.getTaskId());
        if (outboundTask == null) {
            throw new BusinessException("找不到对应的任务");
        }
        //校验任务状态
        //if (!String.valueOf(WmsOutboundTaskStatusEnum.WMS_OUTBOUND_TASK_STATUS_NEW.getValue()).equals(outboundTask.getOtStatus())
        //        && !String.valueOf(WmsOutboundTaskStatusEnum.WMS_OUTBOUND_TASK_STATUS_READY.getValue()).equals(outboundTask.getOtStatus())) {
        //    throw new BusinessException("非已完成状态不可以取消任务");
        //}
        if (String.valueOf(WmsOutboundTaskStatusEnum.WMS_OUTBOUND_TASK_STATUS_FINISHED.getValue()).equals(outboundTask.getOtStatus())
                || String.valueOf(WmsOutboundTaskStatusEnum.WMS_OUTBOUND_TASK_CANCLE.getValue()).equals(outboundTask.getOtStatus())) {
            throw new BusinessException("已完成或取消状态的任务不可取消");
        }

        //更新
        outboundTask.setOtStatus(String.valueOf(WmsOutboundTaskStatusEnum.WMS_OUTBOUND_TASK_CANCLE.getValue()));
        outboundTask.setCancleReason(wmsShipmentPlanRejectBO.getCancleReason());
        wmsOutboundTaskMapper.updateByPrimaryKeySelective(outboundTask);
        //更新库存状态为正常在库
        HashMap<String, Object> paramMap = Maps.newHashMap();
        paramMap.put("status_10", InventoryLocationStatusEnum.NORMAL_10.getCode());
        paramMap.put("status_20", InventoryLocationStatusEnum.DEST_LOCK_20.getCode());
        paramMap.put("status_30", InventoryLocationStatusEnum.BORROW_LOCK_30.getCode());
        paramMap.put("notDel", DeleteFlagEnum.NORMAL.getValue());
        paramMap.put("vin", outboundTask.getOtVin());
        paramMap.put("whCode", wmsShipmentPlanRejectBO.getWhCode());
        int result = wmsInventoryLocationExtMapper.updateInvtoryToNormalListForJM(paramMap);
        if (result <= 0) {
            throw new BusinessException("未查询到该车辆锁定状态的库存信息");
        }
    }


    /**
     * 备料替换
     * <p>
     * 2018-4-27 bugfix 修复调整因入库通知单功能重构,换车匹配车辆的逻辑
     *
     * </p>
     *
     * @param wmsShipmentPlanRejectBO 参数封装
     * @return 返回值
     * @throws Exception 异常
     */
    @Override
    public Map<String, String> updateToReplace(WmsShipmentPlanRejectBO wmsShipmentPlanRejectBO) throws Exception {
        logger.info("WmsShipmentPlanRejectServiceImpl.updateToReplace spId: {}", wmsShipmentPlanRejectBO);
        checkParam(wmsShipmentPlanRejectBO);
        WmsOutboundTask outboundTask = null;
        WmsPreparationVehicleDetail detail = null;
        WmsPreparationPlan preparationPlan = null;

        WmsOutboundTask newTask = null;

        Map<String, String> resultMap = new HashMap<>();

        if (wmsShipmentPlanRejectBO.getTaskId() != null) {
            outboundTask = wmsOutboundTaskMapper.selectByPrimaryKey(wmsShipmentPlanRejectBO.getTaskId());
        }
        if (wmsShipmentPlanRejectBO.getPlanId() != null) {
            preparationPlan = preparationPlanMapper.selectByPrimaryKey(wmsShipmentPlanRejectBO.getPlanId());
        }
        if (wmsShipmentPlanRejectBO.getPlanDetailId() != null) {
            detail = preparationVehicleDetailMapper.selectByPrimaryKey(wmsShipmentPlanRejectBO.getPlanDetailId());
        }

        //校验
        checkChange(outboundTask, preparationPlan, detail);

        //生成新任务
        newTask = new WmsOutboundTask();
        BeanUtils.copyProperties(outboundTask, newTask);

        //ppDetail = new WmsPreparationVehicleDetail();
        //BeanUtils.copyProperties(detail, ppDetail);

        //查询库存, 库位
        String changeVin = null;//替换车架号
        String zoneCode = null;//库区
        String zoneName = null;//
        String localtionCode = null;//库位
        String localtionName = null;//
        List<WmsInventory> wmsInventoryList = null;

        //2018-4-27 bugfix 修复调整因入库通知单功能重构,换车匹配车辆的逻辑
        if (StringUtils.isNotBlank(outboundTask.getOtVin())) {
            WmsWarehouseNoticeDetailExample detailExample = new WmsWarehouseNoticeDetailExample();
            detailExample.createCriteria().andWndVinEqualTo(outboundTask.getOtVin())
                    .andWndDataStatusEqualTo(String.valueOf(DeleteFlagEnum.NORMAL.getValue()))
                    .andWndWarehouseCodeEqualTo(outboundTask.getOtWhCode());
            detailExample.setOrderByClause("wnd_id desc");
            detailExample.setLimitStart(0);
            detailExample.setLimitEnd(1);
            List<WmsWarehouseNoticeDetail> noticeDetails = wmsWarehouseNoticeDetailMapper.selectByExample(detailExample);
            if (CollectionUtils.isNotEmpty(noticeDetails)) {
                WmsWarehouseNoticeDetail noticeDetail = noticeDetails.get(0);
                if (noticeDetail != null) {
                    wmsInventoryList = wmsInventoryService.selectChangeVinForPlanNew(noticeDetail.getWndMaterialCode(),
                            noticeDetail.getWndColorCode(), noticeDetail.getWndVehicleCode(),
                            noticeDetail.getWndWarehouseCode(), outboundTask.getOtVin());
                }
            }
        }
        List<WmsInventoryLocation> locationList = null;
        //判断是否有可以替换的车架号
        if (CollectionUtils.isNotEmpty(wmsInventoryList)) {
            locationList = getLocationList(wmsInventoryList, outboundTask.getOtWhCode());
            if (CollectionUtils.isNotEmpty(locationList)) {
                WmsInventoryLocation location = locationList.get(0);
                changeVin = location.getInvlocVin();
                zoneCode = location.getInvlocZoneCode();
                zoneName = location.getInvlocZoneName();
                localtionCode = location.getInvlocLocCode();
                localtionName = location.getInvlocLocName();
                location.setStatus(InventoryLocationStatusEnum.DEST_LOCK_20.getCode());
                inventoryLocationMapper.updateByPrimaryKeySelective(location);
            }
        }
        if (StringUtils.isBlank(changeVin)) {
            //无车可换
            outboundTask.setOtIsChange(TaskIsNeedChangeEnum.NOT_CAR_TO_CHANGE.getCode());
            if (StringUtils.isNotBlank(outboundTask.getHoHandoverNumber())) {
                WmsShipmentPlanExample shipmentPlanExample = new WmsShipmentPlanExample();
                shipmentPlanExample.setOrderByClause(" sp_id desc ");
                shipmentPlanExample.createCriteria()
                        .andSpSendBusinessFlagEqualTo(String.valueOf(SendBusinessFlagEnum.SEND_Y.getValue()))
                        .andHoHandoverNumberEqualTo(outboundTask.getHoHandoverNumber());
                List<WmsShipmentPlan> wmsShipmentPlanList = shipmentPlanMapper.selectByExample(shipmentPlanExample);
                if (CollectionUtils.isNotEmpty(wmsShipmentPlanList)) {
                    WmsShipmentPlanExample selectPlanExample = new WmsShipmentPlanExample();
                    selectPlanExample.setOrderByClause(" sp_id desc ");
                    selectPlanExample.createCriteria()
                            .andSpSendBusinessFlagEqualTo(String.valueOf(SendBusinessFlagEnum.SEND_Y.getValue()))
                            .andSpGroupBoardNoEqualTo(wmsShipmentPlanList.get(0).getSpGroupBoardNo());
                    List<WmsShipmentPlan> selectPlanList = shipmentPlanMapper.selectByExample(selectPlanExample);
                    if (CollectionUtils.isNotEmpty(selectPlanList)) {
                        WmsShipmentPlan wmsShipmentPlan = selectPlanList.get(0);
                        if (wmsShipmentPlan.getSpRejectNum() == null) {
                            wmsShipmentPlan.setSpRejectNum(1L);
                        } else {
                            wmsShipmentPlan.setSpRejectNum(wmsShipmentPlan.getSpRejectNum() + 1);
                        }

                        shipmentPlanMapper.updateByPrimaryKeySelective(wmsShipmentPlan);
                    }
                }
            }
        } else {
            //有车可换
            restoreOldInvlocCode(outboundTask);

            outboundTask.setOtIsChange(TaskIsNeedChangeEnum.CHANGE_ED.getCode());

            outboundTask.setOtChangeVin(changeVin);

            //更新未出库
            detail.setVdVin(changeVin);
            detail.setVdOutstockStatus(String.valueOf(WmsOutboundStatusEnum.WMS_OUTBOUND_NEW.getValue()));
            //备料详情, 中更新一个备料详情的任务
            preparationVehicleDetailMapper.updateByPrimaryKeySelective(detail);

            //更细主表未进行中
            WmsPreparationPlan updatePlan = new WmsPreparationPlan();
            updatePlan.setPpId(detail.getVdPpId());
            updatePlan.setPpStatus(String.valueOf(WmsPreparationPlanEnum.WMS_PLAN_CONFIRM.getValue()));
            preparationPlanMapper.updateByPrimaryKeySelective(updatePlan);

            //新增任务
            saveNewTask(newTask, changeVin, zoneCode, zoneName, localtionCode, localtionName);
            //新增备料详情
            //saveNewPrepareDetail(ppDetail, changeVin);

            resultMap.put("changeVin", changeVin);//替换的车架号

            changeHandoverOrderNewVin(outboundTask, changeVin);

        }
        //step-1 更新为已替换, 并且更新已经替换的车架号
        wmsOutboundTaskMapper.updateByPrimaryKeySelective(outboundTask);
        resultMap.put("orignialVin", outboundTask.getOtVin());//原有的车架或
        return resultMap;
    }

    private void changeHandoverOrderNewVin(WmsOutboundTask outboundTask, String changeVin) {
        //bugfix 2018-2-5  更新增加接口表中的车架号字段
        WmsHandoverOrderExample orderExample = new WmsHandoverOrderExample();
        orderExample.createCriteria().andZdocEqualTo(outboundTask.getHoHandoverNumber())
                .andSernrEqualTo(outboundTask.getOtVin());
        List<WmsHandoverOrder> wmsHandoverOrders = wmsHandoverOrderMapper.selectByExample(orderExample);
        if (CollectionUtils.isNotEmpty(wmsHandoverOrders)) {
            WmsHandoverOrder wmsHandoverOrder = wmsHandoverOrders.get(0);
            wmsHandoverOrder.setGmtUpdate(new Date());
            wmsHandoverOrder.setSernr(changeVin);
            wmsHandoverOrderMapper.updateByPrimaryKeySelective(wmsHandoverOrder);
        }
    }

    /**
     * 备料替换
     * <p>
     * 2018-3-12 任务完成得车换车后还原库位
     * 2018-4-27 bugfix 修复调整因入库通知单功能重构,换车匹配车辆的逻辑
     * </p>
     *
     * @param byVinDTO 参数
     * @return 返回值
     */
    @Override
    public Map<String, String> updateChangeDetailByVin(WmsChangePreparaByVinDTO byVinDTO) {
        logger.info("WmsShipmentPlanRejectServiceImpl.updateChangeDetailByVin param: {}", JSONObject.toJSONString(byVinDTO));
        if (Objects.equals(byVinDTO, null))
            throw new BusinessException("参数为空!");
        Long taskId = byVinDTO.getTaskId();
        String c_vin = byVinDTO.getChangeVin();
        Long detailId = byVinDTO.getPlanDetailId();
        Long planId = byVinDTO.getPlanId();
        String whCode = byVinDTO.getWhCode();
        if (StringUtils.isBlank(c_vin))
            throw new BusinessException("更换的车架号不能为空!");
        if (taskId == null)
            throw new BusinessException("任务id不能为空!");
        if (detailId == null)
            throw new BusinessException("备料明细id不能为空!");
        if (planId == null)
            throw new BusinessException("计划Id不能为空!");
        if (StringUtils.isBlank(whCode))
            throw new BusinessException("仓库code不能为空!");
        if (!(WhCodeEnum.JM_XY.getValue().equals(whCode)
                || WhCodeEnum.JM_CS.getValue().equals(whCode)))
            throw new BusinessException("该仓库不支持此操作!");

        Map<String, String> resultMap = new HashMap<>();
        WmsOutboundTask outboundTask = wmsOutboundTaskMapper.selectByPrimaryKey(taskId);
        WmsPreparationPlan preparationPlan = preparationPlanMapper.selectByPrimaryKey(planId);
        WmsPreparationVehicleDetail detail = preparationVehicleDetailMapper.selectByPrimaryKey(detailId);
        //校验
        checkChange(outboundTask, preparationPlan, detail);
        if (outboundTask.getOtVin().equals(c_vin)) {
            throw new BusinessException("替换车辆车架号:" + c_vin + "和原车辆车架号一致!");
        }

        //根据换车的车架号查库存
        HashMap<String, Object> c_params = Maps.newHashMap();
        c_params.put("vin", c_vin);
        c_params.put("notDel", DeleteFlagEnum.NORMAL.getValue());
        c_params.put("start", 0);
        c_params.put("end", 1);
        c_params.put("whCode", whCode);
        List<WmsInventoryLocationChangePrepareByVinDTO> c_invlocs = wmsInventoryLocationExtMapper.selectChangePrepareByVin(c_params);
        if (CollectionUtils.isEmpty(c_invlocs)) {
            throw new BusinessException("未查询到该车架号:" + c_vin + "在库信息");
        }
        WmsInventoryLocationChangePrepareByVinDTO c_invloc = c_invlocs.get(0);
        if (!InventoryLocationStatusEnum.NORMAL_10.getCode().equals(c_invloc.getInvlocStatus())) {
            throw new BusinessException("该车架号:" + c_vin + "非正常在库不能进行该操作!");
        }
        //需要换掉的车辆的颜色/物料编码/车型code
        //WmsAsnTempExample wmsAsnTempExample = new WmsAsnTempExample();
        //wmsAsnTempExample.setOrderByClause(" at_id desc ");
        //wmsAsnTempExample.createCriteria().andAtVinEqualTo(outboundTask.getOtVin());
        //List<WmsAsnTemp> wmsAsnTempList = wmsAsnTempMapper.selectByExample(wmsAsnTempExample);
        WmsWarehouseNoticeDetailExample detailExample = new WmsWarehouseNoticeDetailExample();
        detailExample.createCriteria().andWndVinEqualTo(outboundTask.getOtVin())
                .andWndDataStatusEqualTo(String.valueOf(DeleteFlagEnum.NORMAL.getValue()))
                .andWndWarehouseCodeEqualTo(outboundTask.getOtWhCode());
        detailExample.setOrderByClause("wnd_id desc");
        detailExample.setLimitStart(0);
        detailExample.setLimitEnd(1);
        List<WmsWarehouseNoticeDetail> noticeDetails = wmsWarehouseNoticeDetailMapper.selectByExample(detailExample);
        if (CollectionUtils.isNotEmpty(noticeDetails)) {
            WmsWarehouseNoticeDetail noticeDetail = noticeDetails.get(0);
            if (!noticeDetail.getWndMaterialCode().equals(c_invloc.getInvMaterialCode())) {
                throw new BusinessException("替换车辆物料编码:" + c_invloc.getInvMaterialCode() + "不匹配!");
            }
            //if (!noticeDetail.getWndVehicleCode().equals(c_invloc.getInvVehicleSpecName())) {
            //    throw new BusinessException("替换车辆车型编码:" + c_invloc.getInvVehicleSpecName() + "不匹配!");
            //}
            //if (!noticeDetail.getWndColorCode().equals(c_invloc.getInvColorCode())) {
            //    throw new BusinessException("替换车辆颜色编码:" + c_invloc.getInvColorCode() + "不匹配!");
            //}
        }
        //指定的车辆符合要求,生成新任务(可以更换)
        //锁定库存
        WmsInventoryLocation location = new WmsInventoryLocation();
        location.setInvlocId(c_invloc.getInvlocId());
        location.setStatus(InventoryLocationStatusEnum.DEST_LOCK_20.getCode());
        wmsInventoryLocationMapper.updateByPrimaryKeySelective(location);

        //还原老的完成了任务的车辆的库存库位信息
        restoreOldInvlocCode(outboundTask);

        WmsOutboundTask newTask = new WmsOutboundTask();
        BeanUtils.copyProperties(outboundTask, newTask);

        outboundTask.setOtIsChange(TaskIsNeedChangeEnum.CHANGE_ED.getCode());
        outboundTask.setOtChangeVin(c_vin);
        //更新未出库
        detail.setVdVin(c_vin);
        detail.setVdOutstockStatus(String.valueOf(WmsOutboundStatusEnum.WMS_OUTBOUND_NEW.getValue()));
        //备料详情, 中更新一个备料详情的任务
        preparationVehicleDetailMapper.updateByPrimaryKeySelective(detail);

        //更细主表调整进行中
        preparationPlan.setPpStatus(String.valueOf(WmsPreparationPlanEnum.WMS_PLAN_CONFIRM.getValue()));
        preparationPlanMapper.updateByPrimaryKeySelective(preparationPlan);

        //新增任务
        saveNewTask(newTask, c_vin, c_invloc.getInvlocZoneCode(), c_invloc.getInvlocZoneName(),
                c_invloc.getInvlocLocCode(), c_invloc.getInvlocLocName());
        //新增备料详情
        //saveNewPrepareDetail(ppDetail, c_vin);

        //bugfix 2018-2-5  调整接口表中的车架号字段
        changeHandoverOrderNewVin(outboundTask, c_vin);

        //step-1 更新为已替换, 并且更新已经替换的车架号
        wmsOutboundTaskMapper.updateByPrimaryKeySelective(outboundTask);

        resultMap.put("c_vin", c_vin);//替换的车架号

        resultMap.put("orignialVin", outboundTask.getOtVin());//原有的车架或

        return resultMap;
    }

    private void restoreOldInvlocCode(WmsOutboundTask outboundTask) {
        WmsInboundAllocationExample allocationExample = new WmsInboundAllocationExample();
        allocationExample.setOrderByClause("al_id desc");
        allocationExample.setLimitStart(0);
        allocationExample.setLimitEnd(1);
        allocationExample.createCriteria().andAlVinEqualTo(outboundTask.getOtVin());
        //wmsInboundAllocation.
        WmsInboundAllocation wmsInboundAllocation = new WmsInboundAllocation();
        wmsInboundAllocation.setGmtUpdate(new Date());
        wmsInboundAllocation.setAlSourceLocCode(outboundTask.getOtLocationCode());
        wmsInboundAllocation.setAlSourceZoneCode(outboundTask.getOtZoneCode());
        wmsInboundAllocation.setAlSourceZoneName(outboundTask.getOtZoneName());
        wmsInboundAllocation.setIsDeleted(DeleteFlagEnum.NORMAL.getValue());
        wmsInboundAllocationMapper.updateByExampleSelective(wmsInboundAllocation, allocationExample);
        //还原之前的库位,并设置库存状态为冻结---针对是出库验车不合格但是完成任务的数据(未领取任务的通过任务取消不会消除库位)
        WmsInventoryLocationExample locationExample = new WmsInventoryLocationExample();
        locationExample.setOrderByClause("invloc_id desc");
        locationExample.setLimitStart(0);
        locationExample.setLimitEnd(1);
        locationExample.createCriteria()
                .andInvlocVinEqualTo(outboundTask.getOtVin())
                .andInvlocWhCodeEqualTo(outboundTask.getOtWhCode());
        WmsInventoryLocation old_location = new WmsInventoryLocation();
        //不走维修流程。将换下来的车置为冻结状态-还原库位信息
        old_location.setStatus(InventoryLocationStatusEnum.INVENTORY_FREEZE.getCode());
        old_location.setInvlocZoneCode(outboundTask.getOtZoneCode());
        old_location.setInvlocZoneName(outboundTask.getOtZoneName());
        old_location.setInvlocLocCode(outboundTask.getOtLocationCode());
        old_location.setIsDeleted(DeleteFlagEnum.NORMAL.getValue());
        if (StringUtils.isNotBlank(wmsInboundAllocation.getAlSourceLocId())) {
            old_location.setInvlocLocId(Long.valueOf(wmsInboundAllocation.getAlSourceLocId()));
        }
        wmsInventoryLocationMapper.updateByExampleSelective(old_location, locationExample);
    }

    /**
     * 替换的校验
     *
     * @param outboundTask    出库任务
     * @param preparationPlan 备料计划
     * @param detail          备料详情
     */
    private void checkChange(WmsOutboundTask outboundTask,
                             WmsPreparationPlan preparationPlan,
                             WmsPreparationVehicleDetail detail) {
        if (outboundTask == null) {
            throw new BusinessException("找不到对应的任务");
        }
        if (detail == null || preparationPlan == null) {
            throw new BusinessException("找不到对应的备料信息");
        }
        if (TaskIsNeedChangeEnum.CHANGE_ED.getCode().equals(outboundTask.getOtIsChange())
                || TaskIsNeedChangeEnum.NOT_CAR_TO_CHANGE.getCode().equals(outboundTask.getOtIsChange())) {
            throw new BusinessException("当前任务已替换");
        }
        if (StringUtils.isNotBlank(outboundTask.getOtChangeVin())) {
            throw new BusinessException("当前任务已替换");
        }
        //if (String.valueOf(WmsOutboundStatusEnum.WMS_OUTBOUND_FINISH.getValue()).equals(detail.getVdOutstockStatus())) {
        //    //已出库,不能再进行换车--现在君马库在备料完成就变成了已出库状态,用库存状态校验
        //    throw new BusinessException("出库确认车辆不能再换车");
        //}
        if (StringUtils.isNotBlank(outboundTask.getOtVin())) {
            WmsInventoryLocationExample example = new WmsInventoryLocationExample();
            example.createCriteria().andInvlocVinEqualTo(outboundTask.getOtVin());
            List<WmsInventoryLocation> wmsInventoryLocations = wmsInventoryLocationMapper.selectByExample(example);
            if (CollectionUtils.isNotEmpty(wmsInventoryLocations)) {
                WmsInventoryLocation inventoryLocation = wmsInventoryLocations.get(0);
                if (InventoryLocationStatusEnum.MAINTAIN_LOCK_50.getCode().equals(inventoryLocation.getStatus())) {
                    throw new BusinessException("该车辆:" + outboundTask.getOtVin() + "已经出库确认,不支持此操作!");
                }
            }
        }
        //已完成的任务验车异常可进行换车
        if ((String.valueOf(WmsOutboundTaskStatusEnum.WMS_OUTBOUND_TASK_STATUS_FINISHED.getValue()).equals(outboundTask.getOtStatus()))) {
            if (!((WmsOutboundInspectStatusEnum.WAYBILL_DAMAGE.getValue() == (outboundTask.getInspectStatus())) ||
                    (WmsOutboundInspectStatusEnum.WAYBILL_EXCP.getValue() == outboundTask.getInspectStatus()))) {
                throw new BusinessException("已完成任务的车辆只支持验车不合格车辆进行换车!");
            }
            //如果是已取消的任务可以进行换车
        } else if ((!(String.valueOf(WmsOutboundTaskStatusEnum.WMS_OUTBOUND_TASK_CANCLE.getValue()).equals(outboundTask.getOtStatus())))) {
            throw new BusinessException("只能支持已取消任务/已完成且验车不合格车辆换车");
        }
    }

    /**
     * 新增一条任务信息
     */
    private void saveNewTask(WmsOutboundTask newTask, String changeVin, String zoneCode,
                             String zoneName, String localCode, String localtionName) {
        if (newTask != null) {
            //step-2 重新生成一个任务
            newTask.setOtVin(changeVin);
            newTask.setOtStatus(String.valueOf(WmsOutboundTaskStatusEnum.WMS_OUTBOUND_TASK_STATUS_NEW.getValue()));
            newTask.setInspectStatus(WmsOutboundInspectStatusEnum.WAYBILL_INIT.getValue());
            newTask.setOtZoneCode(zoneCode);
            newTask.setOtZoneName(zoneName);
            newTask.setOtLocationCode(localCode);
            newTask.setOtLcoationName(localtionName);
            newTask.setIsDeleted(DeleteFlagEnum.NORMAL.getValue());
            //清空信息
            newTask.setOtExceptionNo("");
            newTask.setOtExceptionType("");
            newTask.setOtExceptionContent("");
            newTask.setCancleReason("");
            newTask.setOtIsChange(TaskIsNeedChangeEnum.NO_CHANGE.getCode());
            newTask.setOtChangeVin("");
            newTask.setGmtCreate(new Date());
            newTask.setGmtModify(new Date());
            newTask.setOtDriver("");//移库司机
            newTask.setOtCheckDesc("");
            newTask.setOtCheckResult("");
            wmsOutboundTaskMapper.insertSelective(newTask);
        }
    }

    /**
     * 创建备料详情
     */
    private void saveNewPrepareDetail(WmsPreparationVehicleDetail ppDetail, String newVin) {
        if (ppDetail != null) {

            ppDetail.setGmtCreate(new Date());
            ppDetail.setVdVin(newVin);
            ppDetail.setGmtUpdate(new Date());
            ppDetail.setIsDeleted(DeleteFlagEnum.NORMAL.getValue());
            ppDetail.setVdOutstockStatus(String.valueOf(WmsOutboundStatusEnum.WMS_OUTBOUND_NEW.getValue()));
            preparationVehicleDetailMapper.insert(ppDetail);
        }
    }

    /**
     * 计划驳回
     */
    private WmsShipmentPlanCancel getCancelList(WmsShipmentPlan shipmentPlan) {

        WmsShipmentPlanCancel cancelShip = new WmsShipmentPlanCancel();
        cancelShip.setPbGroupBoardNo(shipmentPlan.getSpGroupBoardNo());//组版单号
        cancelShip.setPbOrderNo(shipmentPlan.getSpOrderNo());//订单号
        cancelShip.setPbMaterialCode(shipmentPlan.getSpMaterialCode());//物料编码
        //驳回数量
        cancelShip.setPbBackQuantity(shipmentPlan.getSpRejectNum());
        cancelShip.setPbBackTime(new Date());//驳回时间
        cancelShip.setGmtCreate(new Date());
        cancelShip.setGmtUpdate(new Date());
        cancelShip.setSendStatus(SendStatusEnum.SEND_INIT.getValue());
        //spIdList
        return cancelShip;
    }


    /**
     * 参数校验
     */
    private void checkParam(WmsShipmentPlanRejectBO shipmentPlanRejectBO) {
        if (shipmentPlanRejectBO == null) {
            throw new BusinessException("参数为空");
        }
    }

    /**
     * 校验
     */
    private WmsShipmentPlan checkShipment(Long spId) {
        if (spId == null) {
            throw new BusinessException("参数为空");
        }
        WmsShipmentPlan shipmentPlan = shipmentPlanMapper.selectByPrimaryKey(spId);
        if (shipmentPlan == null) {
            throw new BusinessException("找不到对应的发运计划");
        }
        return shipmentPlan;
    }

    /**
     * 根据组版单号获取发运计划列表
     */
    private List<WmsShipmentPlan> getShipmentList(String groupBoardNo) {
        if (StringUtils.isNotBlank(groupBoardNo)) {
            WmsShipmentPlanExample example = new WmsShipmentPlanExample();
            example.createCriteria()
                    .andSpGroupBoardNoEqualTo(groupBoardNo)
                    .andSpSendBusinessFlagEqualTo(String.valueOf(SendBusinessFlagEnum.SEND_Y.getValue()));
            return shipmentPlanMapper.selectByExample(example);
        }
        return null;
    }

    /**
     * 获取根据车架号备料详情
     */
    private WmsPreparationVehicleDetail getDetailByVin(String vin, String ppId) {
        if (StringUtils.isNotBlank(vin)) {
            WmsPreparationVehicleDetailExample example = new WmsPreparationVehicleDetailExample();
            example.createCriteria()
                    .andVdVinEqualTo(vin)
                    .andVdPpIdEqualTo(Long.valueOf(ppId));
            List<WmsPreparationVehicleDetail> detailList = preparationVehicleDetailMapper.selectByExample(example);
            if (CollectionUtils.isNotEmpty(detailList)) {
                return detailList.get(0);
            }
        }
        return null;
    }

    /**
     * 设置列表查询参数
     */
    private void setQueryExample(Map<String, Object> paramMap, WmsShipmentPlanRejectBO shipmentPlanRejectBO) {

        //List<Long> spIdList = shipmentPlanRejectExtMapper.getSpIdListGroupByBoardNo();
        //if (CollectionUtils.isNotEmpty(spIdList)) {
        //    paramMap.put("", spIdList);
        //}
        //订单号
        if (StringUtils.isNotBlank(shipmentPlanRejectBO.getSpOrderNo())) {
            paramMap.put("spOrderNo", shipmentPlanRejectBO.getSpOrderNo());
        }
        //组版单号
        if (StringUtils.isNotBlank(shipmentPlanRejectBO.getSpGroupBoardNo())) {
            //criteria.andSpGroupBoardNoEqualTo(shipmentPlanRejectBO.getSpGroupBoardNo());
            paramMap.put("spGroupBoardNo", shipmentPlanRejectBO.getSpGroupBoardNo());
        }
        //发货仓库
        if (StringUtils.isNotBlank(shipmentPlanRejectBO.getSpDeliverWarehouseCode())) {
            paramMap.put("spDeliverWarehouseCode", shipmentPlanRejectBO.getSpDeliverWarehouseCode());
        }
        //承运商
        if (StringUtils.isNotBlank(shipmentPlanRejectBO.getSpCarrier())) {
            paramMap.put("spCarrier", shipmentPlanRejectBO.getSpCarrier());
        }
        //状态
        //if (StringUtils.isNotBlank(shipmentPlanRejectBO.getSpSendBusinessFlag())) {
        //    paramMap.put("spSendBusinessFlag", shipmentPlanRejectBO.getSpSendBusinessFlag());
        //}
        //发运类型
        if (StringUtils.isNotBlank(shipmentPlanRejectBO.getSpDlvType())) {
            paramMap.put("spDlvType", shipmentPlanRejectBO.getSpDlvType());
        }
        //是否有驳回
        if (StringUtils.isNotBlank(shipmentPlanRejectBO.getSpIsReject())) {
            paramMap.put("spIsReject", shipmentPlanRejectBO.getSpIsReject());
        }
        //创建开始时间
        if (StringUtils.isNotBlank(shipmentPlanRejectBO.getStartCreateTime())) {
            paramMap.put("startCreateTime", DateUtils.StrToDate(shipmentPlanRejectBO.getStartCreateTime(), DateUtils.YYYY_MM_DD));
        }
        //创建结束时间
        if (StringUtils.isNotBlank(shipmentPlanRejectBO.getEndCreateTime())) {
            Date date = DateUtils.StrToDate(shipmentPlanRejectBO.getEndCreateTime(), DateUtils.YYYY_MM_DD);
            date = new Date(date.getTime() + 24 * 60 * 60 * 1000);
            paramMap.put("endCreateTime", date);
        }
    }


    /**
     * 设置详情信息
     */
    private void setDetailInfo(WmsShipmentPlanRejectDetailDTO detailDTO,
                               WmsPreparationVehicleDetail detail) {
        if (detail != null) {
            //detailDTO.setVin(detail.getVdVin());//车架号
            //detailDTO.setVehicleName(detail.getVdVehicleName());//车型
            //detailDTO.setHandoverNo(detail.getHoHandoverNumber());//交接单号
            detailDTO.setCreateDate(detail.getGmtCreate());
            detailDTO.setPlanDetailId(detail.getVdId());
        }
    }

    /**
     * 设置任务信息
     */
    private void setCheckInfo(WmsShipmentPlanRejectDetailDTO detailDTO, WmsOutboundTask outboundTask) {
        if (outboundTask != null) {
            detailDTO.setStatus(outboundTask.getOtStatus());//状态
            detailDTO.setCheckDest(outboundTask.getOtCheckDesc());//检验描述
            detailDTO.setCheckResult(outboundTask.getOtCheckResult());//检验结果
            detailDTO.setTaskNo(outboundTask.getOtTaskNo());//备料任务号
            detailDTO.setMaterOrderNo(outboundTask.getOtPreparationMaterialNo());//备料单号
            detailDTO.setTaskId(outboundTask.getOtId());
            detailDTO.setChangeVin(outboundTask.getOtChangeVin());//替换车架号
            detailDTO.setNeedChange(outboundTask.getOtIsChange());//是否加班
            detailDTO.setCreateDate(outboundTask.getGmtCreate());//创建时间
            detailDTO.setCancleReason(outboundTask.getCancleReason());//取消原因
            detailDTO.setHandoverNo(outboundTask.getHoHandoverNumber());//交接单号
        }
    }

    /**
     * 设置备料信息
     */
    private void setPlanInfo(WmsShipmentPlanRejectDetailDTO detailDTO, WmsPreparationPlan preparationPlan) {
        if (preparationPlan != null) {
            detailDTO.setPlanId(preparationPlan.getPpId());
            //List<WmsInventory> wmsInventoryList = getWmsInventoryList(preparationPlan.getPpMaterialCode(),
            //        preparationPlan.getPpCarColour(), preparationPlan.getPpVehicleName(), preparationPlan.getPpWhCode());
            //if (CollectionUtils.isNotEmpty(wmsInventoryList)){
            //    detailDTO.setNeedChange("是");
            //}else {
            //    detailDTO.setNeedChange("否");
            //}
        }
    }

    /**
     * 获取库存商品
     */
    private List<WmsInventoryLocation> getLocationList(List<WmsInventory> wmsInventoryList, String whCode) {
        if (CollectionUtils.isNotEmpty(wmsInventoryList)) {
            List<Long> invIdList = new ArrayList<>();
            wmsInventoryList.stream()
                    .filter(Objects::nonNull)
                    .filter(inventory -> inventory.getInvId() != null)
                    .forEach(inventory -> invIdList.add(inventory.getInvId()));
            if (CollectionUtils.isNotEmpty(invIdList)) {
                return wmsInventoryService.listInventoryLocation(invIdList, whCode);
            }
        }
        return null;
    }

    private WmsPreparationPlan getPreparationPlan(Long id) {
        if (id != null) {
            return preparationPlanMapper.selectByPrimaryKey(id);
        }
        return null;
    }

    /**
     * 根据交接单号获取任务
     */
    private WmsOutboundTask getTaskByVin(String vin) {
        if (StringUtils.isNotBlank(vin)) {
            WmsOutboundTaskExample taskExample = new WmsOutboundTaskExample();
            taskExample.createCriteria().andOtVinEqualTo(vin);
            List<WmsOutboundTask> outboundTaskList = wmsOutboundTaskMapper.selectByExample(taskExample);
            if (CollectionUtils.isNotEmpty(outboundTaskList)) {
                return outboundTaskList.get(0);
            }
        }
        return null;
    }
}
